﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace Com.PhilChuang.Utils
{
	public static class StreamUtils
	{
		private const int STREAM_BUFFER_SIZE = 128 * 1024; // 128KB

		public static void CopyStream (Stream source, Stream target)
		{ CopyStream (source, target, new byte[STREAM_BUFFER_SIZE]); }

		public static void CopyStream (Stream source, Stream target, byte[] buffer)
		{
			if (source == null) throw new ArgumentNullException ("source");
			if (target == null) throw new ArgumentNullException ("target");

			if (buffer == null) buffer = new byte[STREAM_BUFFER_SIZE];
			int bufferLength = buffer.Length;
			int bytesRead = 0;
			while ((bytesRead = source.Read (buffer, 0, bufferLength)) > 0)
				target.Write (buffer, 0, bytesRead);
		}

		public delegate void PassByteArrayIntRetVoid (byte[] b, int i);

		public static void DoStreamWork (Stream source, PassByteArrayIntRetVoid method)
		{ DoStreamWork (source, null, method); }

		public static void DoStreamWork (Stream source, byte[] buffer, PassByteArrayIntRetVoid method)
		{
			if (source == null) throw new ArgumentNullException ("source");
			if (method == null) throw new ArgumentNullException ("method");

			if (buffer == null)
				buffer = new byte[STREAM_BUFFER_SIZE];
			int bufferLength = buffer.Length;
			int bytesRead = 0;
			while ((bytesRead = source.Read (buffer, 0, bufferLength)) > 0)
				method (buffer, bytesRead);
		}

		public static String ToString (Stream source, Encoding enc)
		{
			if (source == null) throw new ArgumentNullException ("source");

			StringBuilder sb = new StringBuilder ();
			DoStreamWork (source, delegate (byte[] buffer, int bytesRead)
			{
				sb.Append (enc.GetString (buffer, 0, bytesRead));
			});
			return sb.ToString ();
		}
	}
}
